package com.wangnian.batchdemo.utils;


import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.function.BiConsumer;

@Component
public class BatchDmlUtils {

    private static final Logger log = LoggerFactory.getLogger(BatchDmlUtils.class);


    private static SqlSessionFactory sqlSessionFactory;

    @Autowired
    public BatchDmlUtils(SqlSessionFactory sqlSessionFactory) {
        BatchDmlUtils.sqlSessionFactory = sqlSessionFactory;
    }


    public static  <M, T> void batchOperate(List<T> list, Class<M> clazz, BiConsumer<M, T> biConsumer) {
        BatchDmlUtils.batchOperate(list, clazz, 1000,biConsumer);
    }

        /**
         * 批量新增方法
         *
         * @param list       要新增的集合
         * @param clazz      Mapper类
         * @param biConsumer 对应的单条新增方法
         * @param <M>        mapper类型
         * @param <T>        结合元素类型
         */
    public static  <M, T> void batchOperate(List<T> list, Class<M> clazz,int batchSize, BiConsumer<M, T> biConsumer) {
        if (list == null || list.size() == 0) {
            log.error("BatchDmlUtil batchInsert list data is null!");
            throw new RuntimeException("批量新增数据为空！");
        }
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
        try {
            M mapper = sqlSession.getMapper(clazz);
            int i = 1;
            int size = list.size();
            for (T t : list) {
                biConsumer.accept(mapper, t);
                if ((i % batchSize == 0) || i == size) {
                    sqlSession.flushStatements();
                }
                i++;

            }

            //sqlSession.commit();
            sqlSession.clearCache();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("BatchDmlUtil batchInsert is exception！clazz={}", clazz.getName(), e);
            sqlSession.rollback();
            throw new RuntimeException("批量新增失败！");
        } finally {
            sqlSession.close();
        }
    }


}
